/*
 * 文件名： CheckOrderMicroPaySpdbImpl.java
 * 
 * 工程名称: checkorder-service
 *
 * Gopay
 *
 * 创建日期： 2017年11月21日
 *
 * Copyright(C) 2017, by www.gopay.com.cn Inc.All rights reserved.
 *
 * 原始作者: 宣广海
 *
 */
package com.gopay.checkorder.service.impl.micro;

import java.util.List;

import javax.annotation.Resource;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.gopay.checkorder.manager.BankOrderManager;
import com.gopay.checkorder.service.BankOrderService;
import com.gopay.checkorder.service.task.BankCountDownLatch;
import com.gopay.common.Result;
import com.gopay.common.constants.bank.BankOrderStatus;
import com.gopay.common.constants.bank.BisBankBusinessProd;
import com.gopay.common.constants.bank.BisBankInterfaceChannel;
import com.gopay.common.constants.bank.SpdbConstants;
import com.gopay.common.constants.proccode.ProcCodeConstants;
import com.gopay.common.cps.manager.order.CpsGeneralMainOrderQueryManager;
import com.gopay.common.domain.bank.BankOrder;
import com.gopay.common.domain.bank.BaseMessage;
import com.gopay.common.domain.bank.MicroPayBaseMessage;
import com.gopay.common.domain.bank.dayend.BaseDayendEntry;
import com.gopay.common.domain.bank.spdb.agpay.QueryOrderBody;
import com.gopay.common.domain.cashier.BankCardType;
import com.gopay.common.domain.cps.vo.CheckOrderResult;
import com.gopay.common.domain.cps.vo.InAccInfo;
import com.gopay.remote.bank.MicroPayInteractRemoteService;

/**
 * 
 *
 * @author 宣广海
 *
 * @version
 *
 * @since 2017年11月21日
 */
public class CheckOrderMicroPaySpdbImpl implements BankOrderService {

	private final static Logger logger = LoggerFactory.getLogger(CheckOrderMicroPayCiticImpl.class);

	@Resource(name = "microPayClient")
	private MicroPayInteractRemoteService microPayClient;

	@Resource(name = "bankOrderManager")
	protected BankOrderManager bankOrderManager;

	@Resource(name = "cpsGeneralMainOrderQueryManager")
	private CpsGeneralMainOrderQueryManager mainOrderQuery;

	@Override
	public CheckOrderResult checkOrder(BankOrder bankOrder, String target) {
		/**
		 * 对单返回对象
		 */
		CheckOrderResult checkOrderResult = new CheckOrderResult();
		checkOrderResult.setSuccess(false);
		checkOrderResult.setOrderId(bankOrder.getOrderId());

		MicroPayBaseMessage message = new MicroPayBaseMessage();

		message.setOrderId(bankOrder.getOrderId()); // 国付宝系统订单号
		message.setBankOrderId(bankOrder.getOutOrderId());// 上送银行单号
		message.setBankIntrChann(BisBankInterfaceChannel.get(bankOrder.getInterfaceChennelCode()));// 银行通道码
		message.setBankBusProd(BisBankBusinessProd.get(bankOrder.getBankBizProdCode()));// 银行业务产品码
		message.setBank(bankOrder.getBankCode());// 微信、支付宝

		Result result = new Result();
		try {
			if (BisBankBusinessProd._12.value.equals(message.getBankBusProd().value)) {
				// 退款订单处理
				message.setTkOriBankOrderId(bankOrder.getOriOutOrderId());
				result = microPayClient.refundQuery(message);
				return refundCheckOrder(result, bankOrder);
			} else if (BisBankBusinessProd._26.value.equals(message.getBankBusProd().value)) {
				BankOrder oriBankOrder = bankOrderManager.getByGopayOutOrderId(bankOrder.getOriOutOrderId());
				message.setCzOriBankOrderId(bankOrder.getOriOutOrderId());
				message.setCzOriOrderId(oriBankOrder.getOrderId());
				result = microPayClient.reverseQuery(message);
				return reverseCheckOrder(result, bankOrder, target);
			} else {
				// 支付订单处理
				result = microPayClient.orderQuery(message);
			}
			if (result == null || !result.isSuccess()) {
				logger.error("microPayClient fail.");
				if (result == null || ProcCodeConstants.PROC_CODE_100F1002.equals(result.getResultCode())
						|| ProcCodeConstants.PROC_CODE_100E6063.equals(result.getResultCode())) {
					BankCountDownLatch.failIncrease(bankOrder.getBankCode());
				}
				checkOrderResult.setErrCode(ProcCodeConstants.PROC_CODE_100E6022);
				checkOrderResult.setErrMsg("系统返回对账结果为空");
				return checkOrderResult;
			}
			QueryOrderBody res = (QueryOrderBody) result.getDefaultModel();
			if (res == null) {
				/**
				 * 查询结果为空
				 */
				logger.error("fail:orderId:" + bankOrder.getOrderId() + " errcode:"
						+ ProcCodeConstants.PROC_CODE_100E6022 + " err:bis query is null.");
				checkOrderResult.setErrCode(ProcCodeConstants.PROC_CODE_100E6022);
				checkOrderResult.setErrMsg("返回对账结果为空");
				return checkOrderResult;
			}
			if (SpdbConstants.RESPCODE_SUCCESS.equals(res.getRespcd())) {
				checkOrderResult.setSuccess(true);

				InAccInfo accInfo = new InAccInfo();
				accInfo.setOrderId(bankOrder.getOrderId());
				accInfo.setAmount(res.getAmount());
				accInfo.setRetCode("00");
				accInfo.setCardType(BankCardType.Unknown.toString());
				checkOrderResult.setAccInfo(accInfo);
				logger.error("浦发银行条码支付订单：" + bankOrder.getOrderId() + "，交易成功。");
			} else if (SpdbConstants.SPDB_APPAY_RESPCODE_CANC.equals(res.getRespcd())) {
				checkOrderResult.setBankFailure(true);
				checkOrderResult.setErrMsg("条码交易订单已经取消！");
				logger.error("条码支付订单：" + bankOrder.getOrderId() + "，交易失败" + "返回码：" + res.getRespcd() + "。返回信息为："
						+ res.getErrorDetail());
			} else if (StringUtils.equals(SpdbConstants.SPDB_APPAY_RESPCODE_PROCESSING, res.getRespcd())) {
				checkOrderResult.setErrMsg("条码订单进行中！");
				logger.error("条码支付订单：" + bankOrder.getOrderId() + "，交易处理中" + "返回码：" + res.getRespcd() + "。返回信息为："
						+ res.getErrorDetail());
			} else {
				checkOrderResult.setErrMsg("条码返回交易状态不明");
				logger.error("条码支付订单：" + bankOrder.getOrderId() + "，返回交易状态不明，系统暂不处理" + "返回码：" + res.getRespcd()
						+ "。返回信息为：" + res.getErrorDetail());
			}
			return checkOrderResult;
		} catch (Exception e) {
			logger.error("scanClient fail.", e);
			checkOrderResult.setErrCode(ProcCodeConstants.PROC_CODE_100E6022);
			checkOrderResult.setErrMsg("浦发条码对账异常");
			return checkOrderResult;
		}

	}

	public CheckOrderResult reverseCheckOrder(Result result, BankOrder bankOrder, String target) {
	        CheckOrderResult checkOrderResult = new CheckOrderResult();
	        checkOrderResult.setSuccess(false);
	        if (result == null || !result.isSuccess()) {
	            logger.error("microPayClient fail.");
	            if (result == null || ProcCodeConstants.PROC_CODE_100F1002.equals(result.getResultCode())
	                    || ProcCodeConstants.PROC_CODE_100E6063.equals(result.getResultCode())) {
	                BankCountDownLatch.failIncrease(bankOrder.getBankCode());
	            }
	            checkOrderResult.setErrCode(ProcCodeConstants.PROC_CODE_100E6022);
	            checkOrderResult.setErrMsg("系统返回对账结果为空");
	            return checkOrderResult;
	        }
	        QueryOrderBody res = (QueryOrderBody) result.getDefaultModel();
	        if (res == null) {
	            /**
	             * 查询结果为空
	             */
	            logger.error("fail:orderId:" + bankOrder.getOrderId() + " errcode:" + ProcCodeConstants.PROC_CODE_100E6022
	                    + " err:bis query is null.");
	            checkOrderResult.setErrCode(ProcCodeConstants.PROC_CODE_100E6022);
	            checkOrderResult.setErrMsg("返回对账结果为空");
	            return checkOrderResult;
	        }

	        BankOrder oriBankOrder = bankOrderManager.getByGopayOutOrderId(bankOrder.getOriOutOrderId());
	        if (oriBankOrder == null || StringUtils.isBlank(bankOrder.getOrderId())) {
	            checkOrderResult.setErrCode(ProcCodeConstants.PROC_CODE_100E5060);
	            logger.error("bankOrder is null or orderId is null." + bankOrder.toString());
	            return checkOrderResult;
	        }
	        String ordreStatus = oriBankOrder.getOrderStatus();

	            if (SpdbConstants.RESPCODE_SUCCESS.equals(res.getRespcd())) {
	                    // 订单已冲正
	                    if (BankOrderStatus.BANK_CALL_SUCCESS.equals(ordreStatus)
	                            || BankOrderStatus.AUTO_CHECK_SUCCESS.equals(ordreStatus)
	                            || BankOrderStatus.CHECK_SUCCESS.equals(ordreStatus)) {
	                        // 支付成功的订单发起的冲正交易，并且冲正成功
	                        checkOrderResult.setSuccess(true);
	                        InAccInfo accInfo = new InAccInfo();
	                        accInfo.setOrderId(bankOrder.getOrderId());
	                        accInfo.setAmount(bankOrder.getSendBankAmt());
	                        accInfo.setRetCode("00");
	                        accInfo.setCardType(BankCardType.Unknown.toString());
	                        checkOrderResult.setAccInfo(accInfo);
	                    } else {
	                        bankOrderManager.updateSuccess(bankOrder, target);
	                    }
	                    logger.error("冲正订单：" + bankOrder.getOrderId() + ",原支付订单：" + oriBankOrder.getOrderId() + "，交易成功"); 
	            } else {
	                    if (BankOrderStatus.BANK_CALL_SUCCESS.equals(ordreStatus)
	                            || BankOrderStatus.AUTO_CHECK_SUCCESS.equals(ordreStatus)
	                            || BankOrderStatus.CHECK_SUCCESS.equals(ordreStatus)) {
	                        // 支付成功的订单发起的冲正交易，冲正失败
	                        InAccInfo accInfo = new InAccInfo();
	                        accInfo.setOrderId(bankOrder.getOrderId());
	                        accInfo.setAmount(bankOrder.getSendBankAmt());
	                        accInfo.setRetCode("01");
	                        accInfo.setCardType(BankCardType.Unknown.toString());
	                        checkOrderResult.setAccInfo(accInfo);
	                        checkOrderResult.setBankFailure(true);
	                        checkOrderResult.setErrMsg("小额免密查询返回冲正失败！");
	                    } else {
	                        bankOrderManager.updateSuccess(bankOrder, target);
	                    }
	                }
	        return checkOrderResult;
	    }

	/**
	 * 
	 * 功能描述：退款订单对账
	 *
	 * @param result
	 * @param bankOrder
	 * @return
	 * 
	 * @author 宣广海
	 *
	 * @since 2016年10月14日
	 *
	 * @update:[变更日期YYYY-MM-DD][更改人姓名][变更描述]
	 */
	public CheckOrderResult refundCheckOrder(Result result, BankOrder bankOrder) {
		CheckOrderResult checkOrderResult = new CheckOrderResult();
		checkOrderResult.setSuccess(false);
		if (result == null || !result.isSuccess()) {
			logger.error("refund bankClient fail.");
			if (result == null || ProcCodeConstants.PROC_CODE_100F1002.equals(result.getResultCode())
					|| ProcCodeConstants.PROC_CODE_100E7027.equals(result.getResultCode())
					|| ProcCodeConstants.PROC_CODE_100E6063.equals(result.getResultCode())) {
				BankCountDownLatch.failIncrease(bankOrder.getBankCode());
				checkOrderResult.setCommunicateError(true);
			}
			checkOrderResult.setErrCode(ProcCodeConstants.PROC_CODE_100E6062);
			checkOrderResult.setErrMsg("系统返回对账结果为空");
			return checkOrderResult;
		}
		QueryOrderBody res = (QueryOrderBody) result.getDefaultModel();
		if (res == null) {
			// 查询订单为空
			logger.error("fail:orderId:" + bankOrder.getOrderId() + " errcode:" + ProcCodeConstants.PROC_CODE_100E5062
					+ " err:bis query is null.");
			checkOrderResult.setErrCode(ProcCodeConstants.PROC_CODE_100E6022);
			checkOrderResult.setErrMsg("银行返回对账结果为空");
			return checkOrderResult;
		}
		/**
		 * 原交易应答类型
		 */
		if (SpdbConstants.RESPCODE_SUCCESS.equals(res.getRespcd())) {
			// 成功处理
			checkOrderResult.setSuccess(true);
			InAccInfo accInfo = new InAccInfo();
			accInfo.setOrderId(bankOrder.getOrderId());
			accInfo.setAmount(res.getAmount());// 退款金额
			accInfo.setRetCode("00");
			accInfo.setCardType(BankCardType.Unknown.toString());
			checkOrderResult.setAccInfo(accInfo);
			logger.error("扫码支付refund订单：" + bankOrder.getOrderId() + "的交易银行处理成功。" + "返回码：" + res.getRespcd());
		} else if (SpdbConstants.SPDB_APPAY_RESPCODE_NOTEXIST.equals(res.getRespcd())) {
			logger.error("支付refund订单：" + bankOrder.getOrderId() + "的退款交易不存在" + "返回码：" + res.getRespcd() + "，返回信息为："
					+ res.getErrorDetail());
			String errMsg = res.getErrorDetail();
			if (errMsg != null) {
				checkOrderResult.setErrMsg(errMsg);
			} else {
				checkOrderResult.setErrMsg("银行返回退款交易不存在。");
			}
			// 查询订单不存在
			checkOrderResult.setErrCode(ProcCodeConstants.PROC_CODE_100E5041);
		} else if ("Y5".equals(res.getRespcd())) {
			// 失败处理
			checkOrderResult.setBankFailure(true);
			InAccInfo accInfo = new InAccInfo();
			accInfo.setOrderId(bankOrder.getOrderId());
			accInfo.setAmount(res.getAmount());
			accInfo.setRetCode("01");
			accInfo.setCardType(BankCardType.Unknown.toString());
			checkOrderResult.setAccInfo(accInfo);
			logger.error("扫码支付refund订单：" + bankOrder.getOrderId() + "的交易退款失败。" + "返回码：" + res.getRespcd() + "，返回信息为："
					+ res.getErrorDetail());
			String errMsg = res.getErrorDetail();
			if (errMsg != null) {
				checkOrderResult.setErrMsg(errMsg);
			} else {
				checkOrderResult.setErrMsg("银行返回退款交易失败。");
			}
		} else if (StringUtils.equals(SpdbConstants.SPDB_APPAY_RESPCODE_PROCESSING, res.getRespcd())) {
			logger.error("扫码支付refund订单：" + bankOrder.getOrderId() + "的退款交易进行中" + "返回码：" + res.getRespcd() + "，返回信息为："
					+ res.getErrorDetail());
			String errMsg = res.getErrorDetail();
			if (errMsg != null) {
				checkOrderResult.setErrMsg(errMsg);
			} else {
				checkOrderResult.setErrMsg("银行返回退款交易处理中.");
			}
		}
		if (bankOrder.getOrderStatus().equals(BankOrderStatus.ACCEPTED)) {
			checkOrderResult.setErrMsg("系统返回对账结果为空,订单已受理，请耐心等待");
		}
		return checkOrderResult;

	}

	@Override
	public BankOrder getDbOrder() {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public BaseMessage dayend(String bank_bus) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public Result getDayendMsg(String string) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public List<CheckOrderResult> checkDayend(String bank_bus) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public CheckOrderResult checkDayendOrder(BaseDayendEntry bdm, BankOrder bo) {
		// TODO Auto-generated method stub
		return null;
	}

}
